package middleware

import (
	"github.com/gin-gonic/gin"
	"github.com/pkg/errors"
	"net/http"
	"yxs-mall/common/api"
	"yxs-mall/common/middleware/handler"
	"yxs-mall/common/properties"
	"yxs-mall/common/utils"
)

// AuthMiddleware token认证中间件 isMust为true表示必须认证通过, 当isMust=false时，及时token认证失败也能通过
func AuthMiddleware(isMust bool) gin.HandlerFunc {
	return func(c *gin.Context) {
		token := c.GetHeader("authorization")
		if token == "" && isMust {
			c.AbortWithStatusJSON(http.StatusOK, api.TokenError())
			return
		}
		// 当开启token双检时， 先aes解密出真实token
		if err := tokenAesParse(c, &token); err != nil && isMust {
			c.AbortWithStatusJSON(http.StatusOK, api.TokenError())
			return
		}
		// 验证真实token
		if err := tokenParse(c, token); err != nil && isMust {
			c.AbortWithStatusJSON(http.StatusOK, api.TokenError())
			return
		}
		// 执行函数
		c.Next()
		//中间件执行完后续的一些事情
	}
}

func tokenAesParse(c *gin.Context, token *string) error {
	defer func() error {
		if err := recover(); err != nil {
			return errors.New("tokenAesParse panic")
		}
		return nil
	}()
	// 当开启token双检时， 先aes解密出真实token
	tokenDoubleOpen := properties.AppConfig.TokenDoubleOpen
	if tokenDoubleOpen {
		time := c.Query("_t")
		onceToken, err := utils.AesDecryptECBBase64(*token, []byte(time+"cml"))
		if err != nil {
			return err
		}
		if onceToken != nil {
			*token = string(onceToken)
		}
	}
	return nil
}

func tokenParse(c *gin.Context, token string) error {
	defer func() error {
		if err := recover(); err != nil {
			return errors.New("tokenParse panic")
		}
		return nil
	}()
	if token == "" {
		return errors.New("token empty err")
	}

	if token != "" {
		myClaims, err := handler.ParseToken(token)
		// 必须token认证通过
		if err != nil {
			return errors.New("token err")
		}
		if err == nil {
			// 设置变量到Context的key中，可以通过Get()取
			handler.SetContextCurrentUser(c, myClaims)
		}
	}
	return nil
}
